package br.ufal.tci.nexos.arcolive.persistence;

import java.util.LinkedList;

import br.ufal.tci.nexos.arcolive.ArCoLIVEServerProperties;
import br.ufal.tci.nexos.arcolive.exception.ArCoLIVEPersistenceException;

public class ArCoLIVEPersistenceConnectionPoll {

	public LinkedList connections;
	private int capacity;
	private Class implementationClasspath;
	private static ArCoLIVEPersistenceConnectionPoll singleton = null;
	
	private ArCoLIVEPersistenceConnectionPoll() throws ArCoLIVEPersistenceException {
		super();
		this.connections = new LinkedList();
		this.capacity = ArCoLIVEServerProperties.getInstance().getIntProperty("persistence.connectionInPoll");
		try {
			this.implementationClasspath = Class.forName(ArCoLIVEServerProperties.getInstance().getStringProperty("persistence.implementationImpl"));
		} catch (ClassNotFoundException e) {
			throw new ArCoLIVEPersistenceException("Error while trying to load persistence implementation class", e);
		}
		this.inicializePoll();
	}
	
	public static ArCoLIVEPersistenceConnectionPoll getInstance() throws ArCoLIVEPersistenceException {
		if (singleton == null) {
			singleton = new ArCoLIVEPersistenceConnectionPoll();
		}
		return singleton;
	}
	
	private void inicializePoll() throws ArCoLIVEPersistenceException {
		try {
			for (int i = 0; i < this.capacity; i++) {	
				Object object = this.implementationClasspath.newInstance();
				this.connections.add(object);
			}
		} catch (Exception e) {
			throw new ArCoLIVEPersistenceException("Error while inicialize poll", e);
		}
	}
	
	public synchronized ArCoLIVEPersistence getDatabaseConnection() throws ArCoLIVEPersistenceException {
		ArCoLIVEPersistence persistence = null;
		try {
			if (this.connections.isEmpty()) {
				persistence = (ArCoLIVEPersistence) this.implementationClasspath.newInstance();
				if (!persistence.connect()) {
					throw new ArCoLIVEPersistenceException("Error while try to retrieve a connection", null);
				}
				return persistence;
			}
			
			persistence = (ArCoLIVEPersistence) this.connections.getFirst();
			
			if (!persistence.isConnected()) {
				
				persistence.connect();
				
				this.connections.remove(0);
			}
			
		} catch (Exception e) {
			throw new ArCoLIVEPersistenceException("Error while try to retrieve a connection", e);
		}
		
		return persistence;
	}
	
	public synchronized void addDatabaseConnection(ArCoLIVEPersistence gdm) {
		if (!this.connections.contains(gdm)) {
			this.connections.addFirst(gdm);
		}
	}
	
//	public static void main(String[] args) throws Exception {
//		
//		ArCoLIVEPersistenceConnectionPoll poll = new ArCoLIVEPersistenceConnectionPoll();
//		
//		ArCoLIVEPersistence persistence = poll.getDatabaseConnection();
//		
//		ResultSet result = persistence.getAllCountries();
//	
//		ArCoLIVELogRepository.getInstance().log(poll.connections.size());
//		
//		/*while(result.next()) {
//			ArCoLIVELogRepository.getInstance().log(result.getString("countryId"));
//		}*/
//		
//	}
	
}
